package com.smart.translator.util;

import android.content.Context;
import android.util.Log;
import com.konovalov.vad.webrtc.VadWebRTC;
import com.konovalov.vad.webrtc.config.FrameSize;
import com.konovalov.vad.webrtc.config.Mode;
import com.konovalov.vad.webrtc.config.SampleRate;

// Silero VAD相关导入
import com.konovalov.vad.silero.VadSilero;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.ShortBuffer;

/**
 * VAD（Voice Activity Detection）语音活动检测工具类
 * 支持WebRTC VAD和Silero VAD两种检测方法
 */
public class VadDetector {
    private static final String TAG = "VadDetector";
    
    // VAD类型枚举
    public enum VadType {
        WEBRTC("WebRTC VAD"),
        SILERO("Silero VAD");
        
        private final String displayName;
        
        VadType(String displayName) {
            this.displayName = displayName;
        }
        
        public String getDisplayName() {
            return displayName;
        }
    }
    
    // 全局VAD类型设置
    private static VadType currentVadType = VadType.WEBRTC;
    
    // WebRTC VAD相关
    private VadWebRTC webRtcVad;
    private boolean isWebRtcInitialized = false;
    
    // Silero VAD相关
    private VadSilero sileroVad;
    private boolean isSileroInitialized = false;
    
    // 音频参数
    private int sampleRate = 16000; // 默认采样率16kHz
    private int frameSize = 1024; // 默认帧大小（64ms @ 16kHz），兼容Silero VAD
    
    // 上下文
    private Context context;
    
    // VAD检测回调接口
    public interface VadCallback {
        void onSpeechStart();
        void onSpeechEnd();
        void onVoiceActivity(boolean isSpeech);
        void onVadError(String error);
    }
    
    private VadCallback callback;
    
    // VAD状态跟踪
    private boolean isSpeechDetected = false;
    private long speechStartTime = 0;
    private long speechEndTime = 0;
    
    // 音频缓冲区（用于Silero VAD）
    private byte[] audioBuffer = null;
    private int audioBufferPosition = 0;
    private boolean useAudioBuffer = false;

    // 音频缓冲区（用于Silero VAD，short数组版本）
    private short[] shortAudioBuffer = null;
    private int shortAudioBufferPosition = 0;
    
    /**
     * 设置全局VAD类型
     */
    public static void setVadType(VadType vadType) {
        currentVadType = vadType;
        Log.d(TAG, "VAD类型已设置为: " + vadType.getDisplayName());
    }
    
    /**
     * 获取当前VAD类型
     */
    public static VadType getCurrentVadType() {
        return currentVadType;
    }
    
    /**
     * 构造函数
     */
    public VadDetector(Context context) {
        this.context = context.getApplicationContext();
        Log.d(TAG, "VadDetector初始化，当前VAD类型: " + currentVadType.getDisplayName());
    }
    
    /**
     * 设置VAD回调
     */
    public void setCallback(VadCallback callback) {
        this.callback = callback;
    }
    
    /**
     * 初始化VAD检测器
     * @param sampleRate 音频采样率
     * @param frameSize 帧大小
     */
    public void initialize(int sampleRate, int frameSize) {
        this.sampleRate = sampleRate;
        this.frameSize = frameSize;
        
        // 禁用内部音频缓冲区，因为现在在VoskSpeechRecognizer中处理缓冲区
        useAudioBuffer = false;
        audioBuffer = null;
        audioBufferPosition = 0;

        // 重置short音频缓冲区
        shortAudioBuffer = null;
        shortAudioBufferPosition = 0;
        
        Log.d(TAG, "开始初始化VAD检测器，类型: " + currentVadType.getDisplayName());
        
        switch (currentVadType) {
            case WEBRTC:
                initializeWebRtcVad();
                break;
            case SILERO:
                initializeSileroVad();
                break;
        }
    }
    
    /**
     * 初始化WebRTC VAD
     */
    private void initializeWebRtcVad() {
        if (isWebRtcInitialized) {
            Log.d(TAG, "WebRTC VAD已经初始化");
            return;
        }
        
        try {
            // 根据采样率选择对应的SampleRate枚举
            SampleRate sampleRateEnum;
            switch (sampleRate) {
                case 8000:
                    sampleRateEnum = SampleRate.SAMPLE_RATE_8K;
                    break;
                case 16000:
                    sampleRateEnum = SampleRate.SAMPLE_RATE_16K;
                    break;
                case 32000:
                    sampleRateEnum = SampleRate.SAMPLE_RATE_32K;
                    break;
                case 48000:
                    sampleRateEnum = SampleRate.SAMPLE_RATE_48K;
                    break;
                default:
                    sampleRateEnum = SampleRate.SAMPLE_RATE_16K;
                    break;
            }
            
            // 根据帧大小选择对应的FrameSize枚举
            FrameSize frameSizeEnum;
            switch (frameSize) {
                case 80:
                    frameSizeEnum = FrameSize.FRAME_SIZE_80;
                    break;
                case 160:
                    frameSizeEnum = FrameSize.FRAME_SIZE_160;
                    break;
                case 240:
                    frameSizeEnum = FrameSize.FRAME_SIZE_240;
                    break;
                case 320:
                    frameSizeEnum = FrameSize.FRAME_SIZE_320;
                    break;
                case 480:
                    frameSizeEnum = FrameSize.FRAME_SIZE_480;
                    break;
                case 640:
                    frameSizeEnum = FrameSize.FRAME_SIZE_640;
                    break;
                case 960:
                    frameSizeEnum = FrameSize.FRAME_SIZE_960;
                    break;
                default:
                    frameSizeEnum = FrameSize.FRAME_SIZE_320;
                    break;
            }
            
            // 创建WebRTC VAD实例
            webRtcVad = new VadWebRTC(
                sampleRateEnum,
                frameSizeEnum,
                Mode.VERY_AGGRESSIVE, // 非常激进的检测模式
                300, // 静音持续时间阈值（毫秒）
                50   // 语音持续时间阈值（毫秒）
            );
            
            isWebRtcInitialized = true;
            Log.d(TAG, "WebRTC VAD初始化成功 - 采样率: " + sampleRate + "Hz, 帧大小: " + frameSize);
            
        } catch (Exception e) {
            Log.e(TAG, "WebRTC VAD初始化失败", e);
            isWebRtcInitialized = false;
            if (callback != null) {
                callback.onVadError("WebRTC VAD初始化失败: " + e.getMessage());
            }
        }
    }
    
    /**
     * 初始化Silero VAD
     */
    private void initializeSileroVad() {
        if (isSileroInitialized) {
            Log.d(TAG, "Silero VAD已经初始化");
            return;
        }
        
        try {
            // 根据采样率选择对应的Silero SampleRate枚举
            com.konovalov.vad.silero.config.SampleRate sileroSampleRate;
            switch (sampleRate) {
                case 8000:
                    sileroSampleRate = com.konovalov.vad.silero.config.SampleRate.SAMPLE_RATE_8K;
                    break;
                case 16000:
                    sileroSampleRate = com.konovalov.vad.silero.config.SampleRate.SAMPLE_RATE_16K;
                    break;
                default:
                    sileroSampleRate = com.konovalov.vad.silero.config.SampleRate.SAMPLE_RATE_16K;
                    break;
            }
            
            // 根据帧大小选择对应的Silero FrameSize枚举
            com.konovalov.vad.silero.config.FrameSize sileroFrameSize;
            switch (frameSize) {
                case 256:
                    sileroFrameSize = com.konovalov.vad.silero.config.FrameSize.FRAME_SIZE_256;
                    break;
                case 512:
                    sileroFrameSize = com.konovalov.vad.silero.config.FrameSize.FRAME_SIZE_512;
                    break;
                case 768:
                    sileroFrameSize = com.konovalov.vad.silero.config.FrameSize.FRAME_SIZE_768;
                    break;
                case 1024:
                    sileroFrameSize = com.konovalov.vad.silero.config.FrameSize.FRAME_SIZE_1024;
                    break;
                case 1536:
                    sileroFrameSize = com.konovalov.vad.silero.config.FrameSize.FRAME_SIZE_1536;
                    break;
                default:
                    // 根据采样率选择默认帧大小
                    if (sampleRate == 8000) {
                        sileroFrameSize = com.konovalov.vad.silero.config.FrameSize.FRAME_SIZE_512;
                    } else {
                        sileroFrameSize = com.konovalov.vad.silero.config.FrameSize.FRAME_SIZE_1024;
                    }
                    break;
            }
            
            // 创建Silero VAD实例
            sileroVad = new VadSilero(
                context,
                sileroSampleRate,
                sileroFrameSize,
                com.konovalov.vad.silero.config.Mode.AGGRESSIVE, // 使用更严格的模式
                100, // 增加语音持续时间阈值（毫秒）
                500  // 增加静音持续时间阈值（毫秒）
            );
            
            isSileroInitialized = true;
            Log.d(TAG, "Silero VAD初始化成功 - 采样率: " + sampleRate + "Hz, 帧大小: " + frameSize);
            
        } catch (Exception e) {
            Log.e(TAG, "Silero VAD初始化失败", e);
            isSileroInitialized = false;
            if (callback != null) {
                callback.onVadError("Silero VAD初始化失败: " + e.getMessage());
            }
        }
    }
    
    /**
     * 处理音频数据
     * @param audioData 音频数据（PCM格式）
     * @return 是否检测到语音活动
     */
    public boolean processAudio(byte[] audioData) {
        if (audioData == null || audioData.length == 0) {
            return false;
        }
        
        switch (currentVadType) {
            case WEBRTC:
                return processAudioWebRtc(audioData);
            case SILERO:
                return processAudioSilero(audioData);
            default:
                Log.w(TAG, "未知的VAD类型: " + currentVadType);
                return false;
        }
    }
    
    /**
     * 使用WebRTC VAD处理音频数据
     */
    private boolean processAudioWebRtc(byte[] audioData) {
        if (!isWebRtcInitialized || webRtcVad == null) {
            Log.w(TAG, "WebRTC VAD未初始化，尝试重新初始化");
            initializeWebRtcVad();
            if (!isWebRtcInitialized) {
                return false;
            }
        }
        
        try {
            // 使用WebRTC VAD检测语音
            boolean isSpeech = webRtcVad.isSpeech(audioData);
            
            // 状态变化检测
            boolean previousSpeechState = isSpeechDetected;
            isSpeechDetected = isSpeech;
            
            // 通知回调
            if (callback != null) {
                callback.onVoiceActivity(isSpeech);
                
                // 检测语音开始
                if (isSpeech && !previousSpeechState) {
                    speechStartTime = System.currentTimeMillis();
                    callback.onSpeechStart();
                    Log.d(TAG, "🎤 WebRTC VAD检测到语音开始");
                }
                
                // 检测语音结束
                if (!isSpeech && previousSpeechState) {
                    speechEndTime = System.currentTimeMillis();
                    callback.onSpeechEnd();
                    long duration = speechEndTime - speechStartTime;
                    Log.d(TAG, "🔇 WebRTC VAD检测到语音结束，持续时间: " + duration + "ms");
                }
            }
            
            return isSpeech;
            
        } catch (Exception e) {
            Log.e(TAG, "WebRTC VAD处理音频数据失败", e);
            return false;
        }
    }
    
    /**
     * 使用Silero VAD处理音频数据
     */
    private boolean processAudioSilero(byte[] audioData) {
        if (!isSileroInitialized || sileroVad == null) {
            Log.w(TAG, "Silero VAD未初始化，尝试重新初始化");
            initializeSileroVad();
            if (!isSileroInitialized) {
                return false;
            }
        }
        
        try {
            // 为Silero VAD启用音频缓冲区机制
            if (audioBuffer == null) {
                int expectedBytes = frameSize * 2; // 每个样本2字节
                audioBuffer = new byte[expectedBytes];
                audioBufferPosition = 0;
                Log.d(TAG, "初始化Silero VAD音频缓冲区: " + expectedBytes + "字节");
            }
            
            // 将音频数据累积到缓冲区
            int remainingSpace = audioBuffer.length - audioBufferPosition;
            int bytesToCopy = Math.min(audioData.length, remainingSpace);
            
            System.arraycopy(audioData, 0, audioBuffer, audioBufferPosition, bytesToCopy);
            audioBufferPosition += bytesToCopy;
            
            // 如果缓冲区已满，进行VAD检测
            if (audioBufferPosition >= audioBuffer.length) {
                // 使用Silero VAD进行检测
                boolean isSpeech = sileroVad.isSpeech(audioBuffer);
                
                // 状态变化检测
                boolean previousSpeechState = isSpeechDetected;
                isSpeechDetected = isSpeech;
                
                // 通知回调
                if (callback != null) {
                    callback.onVoiceActivity(isSpeech);
                    
                    // 检测语音开始
                    if (isSpeech && !previousSpeechState) {
                        speechStartTime = System.currentTimeMillis();
                        callback.onSpeechStart();
                        Log.d(TAG, "🎤 Silero VAD检测到语音开始");
                    }
                    
                    // 检测语音结束
                    if (!isSpeech && previousSpeechState) {
                        speechEndTime = System.currentTimeMillis();
                        callback.onSpeechEnd();
                        long duration = speechEndTime - speechStartTime;
                        Log.d(TAG, "🔇 Silero VAD检测到语音结束，持续时间: " + duration + "ms");
                    }
                }
                
                // 重置缓冲区
                audioBufferPosition = 0;
                
                return isSpeech;
            } else {
                // 缓冲区未满，返回上一次的检测结果
                return isSpeechDetected;
            }
            
        } catch (Exception e) {
            Log.e(TAG, "Silero VAD处理音频数据失败", e);
            return false;
        }
    }
    
    /**
     * 处理音频数据（short数组格式）
     * @param pcmData 音频数据（PCM格式，short数组）
     * @return 是否检测到语音活动
     */
    public boolean processAudio(short[] pcmData) {
        if (pcmData == null || pcmData.length == 0) {
            return false;
        }
        
        switch (currentVadType) {
            case WEBRTC:
                return processAudioWebRtc(pcmData);
            case SILERO:
                return processAudioSilero(pcmData);
            default:
                Log.w(TAG, "未知的VAD类型: " + currentVadType);
                return false;
        }
    }
    
    /**
     * 使用WebRTC VAD处理音频数据（short数组格式）
     */
    private boolean processAudioWebRtc(short[] pcmData) {
        if (!isWebRtcInitialized || webRtcVad == null) {
            Log.w(TAG, "WebRTC VAD未初始化，尝试重新初始化");
            initializeWebRtcVad();
            if (!isWebRtcInitialized) {
                return false;
            }
        }
        
        try {
            // 使用WebRTC VAD检测语音
            boolean isSpeech = webRtcVad.isSpeech(pcmData);
            
            // 状态变化检测
            boolean previousSpeechState = isSpeechDetected;
            isSpeechDetected = isSpeech;
            
            // 通知回调
            if (callback != null) {
                callback.onVoiceActivity(isSpeech);
                
                // 检测语音开始
                if (isSpeech && !previousSpeechState) {
                    speechStartTime = System.currentTimeMillis();
                    callback.onSpeechStart();
                    Log.d(TAG, "🎤 WebRTC VAD检测到语音开始");
                }
                
                // 检测语音结束
                if (!isSpeech && previousSpeechState) {
                    speechEndTime = System.currentTimeMillis();
                    callback.onSpeechEnd();
                    long duration = speechEndTime - speechStartTime;
                    Log.d(TAG, "🔇 WebRTC VAD检测到语音结束，持续时间: " + duration + "ms");
                }
            }
            
            return isSpeech;
            
        } catch (Exception e) {
            Log.e(TAG, "WebRTC VAD处理音频数据失败", e);
            return false;
        }
    }
    
    /**
     * 使用Silero VAD处理音频数据（short数组格式）
     */
    private boolean processAudioSilero(short[] pcmData) {
        if (!isSileroInitialized || sileroVad == null) {
            Log.w(TAG, "Silero VAD未初始化，尝试重新初始化");
            initializeSileroVad();
            if (!isSileroInitialized) {
                return false;
            }
        }
        
        try {
            // 为Silero VAD启用音频缓冲区机制（short数组版本）
            if (shortAudioBuffer == null) {
                shortAudioBuffer = new short[frameSize];
                shortAudioBufferPosition = 0;
                Log.d(TAG, "初始化Silero VAD音频缓冲区(short): " + frameSize + "样本");
            }
            
            // 将音频数据累积到缓冲区
            int remainingSpace = shortAudioBuffer.length - shortAudioBufferPosition;
            int samplesToCopy = Math.min(pcmData.length, remainingSpace);
            
            System.arraycopy(pcmData, 0, shortAudioBuffer, shortAudioBufferPosition, samplesToCopy);
            shortAudioBufferPosition += samplesToCopy;
            
            // 如果缓冲区已满，进行VAD检测
            if (shortAudioBufferPosition >= shortAudioBuffer.length) {
                // 使用Silero VAD进行检测
                boolean isSpeech = sileroVad.isSpeech(shortAudioBuffer);
                
                // 状态变化检测
                boolean previousSpeechState = isSpeechDetected;
                isSpeechDetected = isSpeech;
                
                // 通知回调
                if (callback != null) {
                    callback.onVoiceActivity(isSpeech);
                    
                    // 检测语音开始
                    if (isSpeech && !previousSpeechState) {
                        speechStartTime = System.currentTimeMillis();
                        callback.onSpeechStart();
                        Log.d(TAG, "🎤 Silero VAD检测到语音开始");
                    }
                    
                    // 检测语音结束
                    if (!isSpeech && previousSpeechState) {
                        speechEndTime = System.currentTimeMillis();
                        callback.onSpeechEnd();
                        long duration = speechEndTime - speechStartTime;
                        Log.d(TAG, "🔇 Silero VAD检测到语音结束，持续时间: " + duration + "ms");
                    }
                }
                
                // 重置缓冲区
                shortAudioBufferPosition = 0;
                
                return isSpeech;
            } else {
                // 缓冲区未满，返回上一次的检测结果
                return isSpeechDetected;
            }
            
        } catch (Exception e) {
            Log.e(TAG, "Silero VAD处理音频数据失败", e);
            return false;
        }
    }
    
    /**
     * 重置VAD状态
     */
    public void reset() {
        isSpeechDetected = false;
        speechStartTime = 0;
        speechEndTime = 0;
        
        // 清理音频缓冲区
        if (audioBuffer != null) {
            audioBufferPosition = 0;
            // 用零填充缓冲区
            for (int i = 0; i < audioBuffer.length; i++) {
                audioBuffer[i] = 0;
            }
            Log.d(TAG, "音频缓冲区已重置");
        }

        // 清理short音频缓冲区
        if (shortAudioBuffer != null) {
            shortAudioBufferPosition = 0;
            // 用零填充缓冲区
            for (int i = 0; i < shortAudioBuffer.length; i++) {
                shortAudioBuffer[i] = 0;
            }
            Log.d(TAG, "short音频缓冲区已重置");
        }
        
        // 重新初始化当前VAD类型
        switch (currentVadType) {
            case WEBRTC:
                isWebRtcInitialized = false;
                if (webRtcVad != null) {
                    try {
                        webRtcVad.close();
                    } catch (Exception e) {
                        Log.e(TAG, "关闭WebRTC VAD失败", e);
                    }
                    webRtcVad = null;
                }
                break;
            case SILERO:
                isSileroInitialized = false;
                if (sileroVad != null) {
                    try {
                        sileroVad.close();
                    } catch (Exception e) {
                        Log.e(TAG, "关闭Silero VAD失败", e);
                    }
                    sileroVad = null;
                }
                break;
        }
        
        Log.d(TAG, "VAD状态已重置");
    }
    
    /**
     * 释放资源
     */
    public void release() {
        // 关闭WebRTC VAD
        if (webRtcVad != null) {
            try {
                webRtcVad.close();
                Log.d(TAG, "WebRTC VAD已关闭");
            } catch (Exception e) {
                Log.e(TAG, "关闭WebRTC VAD失败", e);
            }
            webRtcVad = null;
        }
        isWebRtcInitialized = false;
        
        // 关闭Silero VAD
        if (sileroVad != null) {
            try {
                sileroVad.close();
                Log.d(TAG, "Silero VAD已关闭");
            } catch (Exception e) {
                Log.e(TAG, "关闭Silero VAD失败", e);
            }
            sileroVad = null;
        }
        isSileroInitialized = false;
        
        // 重置状态
        isSpeechDetected = false;
        speechStartTime = 0;
        speechEndTime = 0;
        
        // 清理音频缓冲区
        audioBuffer = null;
        audioBufferPosition = 0;
        useAudioBuffer = false;

        // 清理short音频缓冲区
        shortAudioBuffer = null;
        shortAudioBufferPosition = 0;
        
        Log.d(TAG, "VAD资源已释放");
    }
    
    /**
     * 检查VAD是否已初始化
     */
    public boolean isInitialized() {
        switch (currentVadType) {
            case WEBRTC:
                return isWebRtcInitialized;
            case SILERO:
                return isSileroInitialized;
            default:
                return false;
        }
    }
    
    /**
     * 获取当前采样率
     */
    public int getSampleRate() {
        return sampleRate;
    }
    
    /**
     * 获取当前帧大小
     */
    public int getFrameSize() {
        return frameSize;
    }
    
    /**
     * 检查是否检测到语音
     */
    public boolean isSpeechDetected() {
        return isSpeechDetected;
    }
    
    /**
     * 获取语音开始时间
     */
    public long getSpeechStartTime() {
        return speechStartTime;
    }
    
    /**
     * 获取语音结束时间
     */
    public long getSpeechEndTime() {
        return speechEndTime;
    }
    
    /**
     * 获取语音持续时间
     */
    public long getSpeechDuration() {
        if (speechStartTime > 0 && speechEndTime > 0) {
            return speechEndTime - speechStartTime;
        }
        return 0;
    }
    
    /**
     * 切换VAD类型
     */
    public void switchVadType(VadType newVadType) {
        if (currentVadType == newVadType) {
            Log.d(TAG, "VAD类型已经是: " + newVadType.getDisplayName());
            return;
        }
        
        Log.d(TAG, "切换VAD类型: " + currentVadType.getDisplayName() + " -> " + newVadType.getDisplayName());
        
        // 释放当前VAD资源
        release();
        
        // 设置新的VAD类型
        currentVadType = newVadType;
        
        // 重新初始化
        initialize(sampleRate, frameSize);
    }
    
    /**
     * 获取VAD状态信息
     */
    public String getStatusInfo() {
        StringBuilder info = new StringBuilder();
        info.append("VAD类型: ").append(currentVadType.getDisplayName()).append("\n");
        info.append("采样率: ").append(sampleRate).append("Hz\n");
        info.append("帧大小: ").append(frameSize).append("\n");
        info.append("已初始化: ").append(isInitialized()).append("\n");
        info.append("检测到语音: ").append(isSpeechDetected).append("\n");
        
        if (speechStartTime > 0) {
            info.append("语音开始时间: ").append(speechStartTime).append("ms\n");
        }
        if (speechEndTime > 0) {
            info.append("语音结束时间: ").append(speechEndTime).append("ms\n");
        }
        if (getSpeechDuration() > 0) {
            info.append("语音持续时间: ").append(getSpeechDuration()).append("ms\n");
        }
        
        return info.toString();
    }
} 
